//圆形Image扩展组件，支持圆形碰撞检测
using UnityEngine;
using UnityEngine.UI;

namespace BToolkit
{
    [AddComponentMenu("UI/CircleImage")]
    public class CircleImage : Image
    {
        public int detail = 20;
        public float texScale = 1;

        protected override void OnPopulateMesh(VertexHelper vh)
        {
            vh.Clear();

            Vector2 size = rectTransform.sizeDelta;
            //圆心
            Vector2 centerUV = Vector2.zero;
            Vector2 centerPoint = Vector2.zero;
            centerPoint.x += size.x * (0.5f - rectTransform.pivot.x);
            centerPoint.y += size.y * (0.5f - rectTransform.pivot.y);
            AddVertex(vh, centerPoint, centerUV, size);
            //外圈
            float incRadian = Mathf.Deg2Rad * 360 / detail;
            int renderCount = detail;
            if (type == Type.Filled)
            {
                renderCount = Mathf.CeilToInt(detail * fillAmount);
            }
            for (int i = 0; i < renderCount; i++)
            {
                float r = incRadian * i;
                Vector2 uv, point;
                uv.x = Mathf.Cos(r) * size.x * 0.5f;
                uv.y = Mathf.Sin(r) * size.y * 0.5f;
                point.x = uv.x + size.x * (0.5f - rectTransform.pivot.x);
                point.y = uv.y + size.y * (0.5f - rectTransform.pivot.y);
                AddVertex(vh, point, uv, size);
            }

            AddTriangle(vh, renderCount);
        }

        /// <summary>
        /// 添加顶点数据
        /// </summary>
        private void AddVertex(VertexHelper vh, Vector2 pos, Vector2 uv, Vector2 size)
        {
            UIVertex vertex = UIVertex.simpleVert;
            vertex.color = color;
            vertex.position = pos;
            Vector2 uv0 = new Vector2((uv.x + size.x * 0.5f) / size.x, (uv.y + size.y * 0.5f) / size.y);

            //支持贴图缩放
            uv0 *= texScale;
            uv0 -= Vector2.one * (texScale - 1f) * 0.5f;

            vertex.uv0 = uv0;
            vh.AddVert(vertex);
        }

        void AddTriangle(VertexHelper vh, int count)
        {
            for (int i = 1; i <= count; i++)
            {
                if (i < count)
                {
                    vh.AddTriangle(0, i, i + 1);
                }
                else
                {
                    if (type == Type.Filled)
                    {
                        if (fillAmount == 1)
                        {
                            vh.AddTriangle(0, i, 1);
                        }
                    }
                    else
                    {
                        vh.AddTriangle(0, i, 1);
                    }
                }
            }
        }

        //重写点击判断
        public override bool IsRaycastLocationValid(Vector2 screenPoint, Camera eventCamera)
        {
            //用所有连线判断相交次数的奇偶太耗性能，这里简单处理：取最长轴为直径假定为正圆，判断在此正圆内即为点中
            Vector2 clickPos;
            RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, screenPoint, eventCamera, out clickPos);
            float radius = rectTransform.sizeDelta.x * 0.5f;
            if (rectTransform.sizeDelta.y * 0.5f > radius) radius = rectTransform.sizeDelta.y * 0.5f;
            return Vector2.Distance(clickPos, Vector2.zero) <= radius;
        }

#if UNITY_EDITOR
        [UnityEditor.MenuItem("GameObject/UI/Circle Image")]
        static void Create()
        {
            GameObject go = new GameObject("CircleImage");
            go.transform.SetParent(UnityEditor.Selection.activeGameObject.transform, false);
            go.AddComponent<CircleImage>();
        }
#endif

    }

}